using FytSoa.Domain.Sys;
using FytSoa.Sugar;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
using AutoMapper;
using FytSoa.Common.Utils;
using FytSoa.Domain.Core.Param;
using FytSoa.Domain.Core.Result;
using Masuit.Tools.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using System.Linq;
using FytSoa.Comment.Utils;
using System.IO;

namespace FytSoa.Application.Sys
{
    /// <summary>
    /// 资源文件信息表 服务接口
    /// </summary>
    [ApiExplorerSettings(GroupName = "v1")]
    public class SysFileInfoService : SugarRepository<SysFileInfo>,ISysFileInfoService 
    {
        private readonly IMapper _mapper;
        private readonly ISysSafetyService _safetyService;
        public SysFileInfoService(IMapper mapper
            , ISysSafetyService safetyService)
        {
            _mapper = mapper;
            _safetyService= safetyService;
        }
        
        /// <summary>
        /// 查询所有——分页
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<ApiResult<PageResult<SysFileInfoDto>>> GetPagesAsync(PageParam<CommonParam> param)
        {
            Expression<Func<SysFileInfo, bool>> where = m => true;
            var (list,totalItems,totalPage) = await base.GetPageResultAsync(where, param.Page, param.Limit, m => m.Id);
            var result = new PageResult<SysFileInfoDto>()
            {
                Items = _mapper.Map<List<SysFileInfoDto>>(list),
                TotalItems = totalItems,
                TotalPages = totalPage
            };
            return JResult<PageResult<SysFileInfoDto>>.Success(result);
        }

        /// <summary>
        /// 根据主键查询
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("{id}")]
        public async Task<ApiResult<SysFileInfoDto>> GetAsync(long id)
        {
            return JResult<SysFileInfoDto>.Success(_mapper.Map<SysFileInfoDto>(await base.GetByIdAsync(id)));
        }

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<ApiResult<bool>> AddAsync(SysFileInfoDto model)
        {
            return JResult<bool>.Success(await base.InsertAsync(_mapper.Map<SysFileInfo>(model)));
        }

        /// <summary>
        /// 上传文件
        /// </summary>
        /// <returns></returns>
        public async Task<ApiResult<FileDto>> Upload(IFormFile file, string columnId, string user)
        {
            var safety = _safetyService.Get();
            //原文件名
            var filename = file.FileName;
            //扩展名
            var fileExt = FileUtils.GetFileExt(filename);
            if (!string.IsNullOrEmpty(safety.Data.UploadBlack))
            {
                var arr = safety.Data.UploadBlack.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
                if (arr.Contains(fileExt))
                {
                    return JResult<FileDto>.Error("文件类型存在【上传黑名单】中，不允许上传~");
                }
            }
            if (!string.IsNullOrEmpty(safety.Data.UploadWhite))
            {
                var arr = safety.Data.UploadWhite.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
                if (!arr.Contains(fileExt))
                {
                    return JResult<FileDto>.Error("文件类型不存在【上传白名单】中，不允许上传~");
                }
            }
            //判断是否包含盘符： 文件名不允许包含冒号，如果存在，则使用新的文件名字
            if (filename.Contains(":"))
            {
                filename = DateTime.Now.GetTimeStamp() + "." + fileExt;
            }
            var path = CommonUtils.AssigendPath(fileExt, "");
            var basePath = FileUtils.MapPath(path);
            FileUtils.CreateSuffic(FileUtils.MapPath(path));
            using (var stream = new FileStream(basePath + filename, FileMode.Create))
            {
                file.CopyTo(stream);
                stream.Flush();
            }
            var model = new SysFileInfo()
            {
                Id = Unique.Id(),
                ColumnId = Int64.Parse(columnId),
                Name = filename,
                FileUrl = path + filename,
                FileType = fileExt,
                FileSize = Convert.ToInt64(Math.Round(Convert.ToDecimal(file.Length / 1024), 0)),
                CreateUser = user
            };
            await base.InsertAsync(model);
            return JResult<FileDto>.Success(new FileDto()
            {
                path = model.FileUrl,
                name = model.Name,
                size = model.FileSize
            });
        }

        /// <summary>
        /// 文件移动
        /// </summary>
        /// <returns></returns>
        public async Task<ApiResult<bool>> Move(FileMoveParam param)
        {
            return JResult<bool>.Success(await base.UpdateAsync(m=>new SysFileInfo() { ColumnId=param.ColumnId }, m => m.Id == param.Id));
        }

        /// <summary>
        /// 文件复制
        /// </summary>
        /// <returns></returns>
        public async Task<ApiResult<bool>> Copy(FileCopyParam param)
        {
            var isExits = await base.IsAnyAsync(m => m.Id == param.Id && m.ColumnId == param.ColumnId);
            if (isExits)
            {
                return JResult<bool>.Error("当前栏目已存在相同的文件~");
            }
            var sourceModel = await base.GetByIdAsync(param.Id);
            sourceModel.Id = Unique.Id();
            sourceModel.ColumnId = param.ColumnId;
            sourceModel.CreateTime = DateTime.Now;
            return JResult<bool>.Success(await base.InsertAsync(sourceModel));
        }

        /// <summary>
        /// 文件重命名
        /// </summary>
        /// <returns></returns>
        public async Task<ApiResult<bool>> ReName(FileReNameParam param)
        {
            var fileModel = await base.GetByIdAsync(param.Id);
            if (string.IsNullOrEmpty(param.fileName))
            {
                return JResult<bool>.Error("文件新名称不能为空~");
            }
            fileModel.Name = param.fileName;
            var sourceName = FileUtils.GetFileName(FileUtils.MapPath(fileModel.FileUrl));
            var sourcePath = fileModel.FileUrl.Replace(sourceName, "");
            FileUtils.FileReName(fileModel.FileUrl, sourcePath + param.fileName);
            var newPath = sourcePath + param.fileName;
            return JResult<bool>.Success(await base.UpdateAsync(m => new SysFileInfo()
            {
                FileUrl = newPath,
                Name = param.fileName
            }
            , m => m.Id == param.Id));
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<ApiResult<bool>> ModifyAsync(SysFileInfoDto model)
        {
            return JResult<bool>.Success(await base.UpdateAsync(_mapper.Map<SysFileInfo>(model)));
        }

        /// <summary>
        /// 删除,支持多个
        /// </summary>
        /// <param name="ids">逗号分隔</param>
        /// <returns></returns>
        public async Task<ApiResult<bool>> DeleteAsync(string ids)
        {
            var id = ids.StrToListLong();
            return JResult<bool>.Success(await base.DeleteAsync(m=>id.Contains(m.Id)));
        }
    }
}
